using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class GameController : MonoBehaviour{
	
	#region Scene reference
	public GameObject Panel_NoneState;
	public GameObject Panel_PlayingState;
	public GameObject Panel_GameoverState;
	public GameObject Panel_HelpState;
	public BirdFactory birdFactory;
	public GameObject pauseGame;
	public UILabel lblScore;
	#endregion
	
	#region fields
	GameState _currentState = GameState.None;
	List<KeyValuePair<GameState, GameObject>> _Panels = new List<KeyValuePair<GameState, GameObject>>();
	Queue<GameObject> _birdsInScene = new Queue<GameObject>();
	const int MAX_QUEUE = 30;
	const int LOSE = 3;
	const int LEVEL_UP = 20;
	int _score = 0;
	int _penalty = 0;
	bool isPaused = false;
	public static GameController Instance;
	#endregion
	
	#region functions
	IEnumerator StartClearScene(){
		yield return new WaitForEndOfFrame();
		_birdsInScene.Clear();
		BroadcastMessage("ClearScene");
		UpdatePanels();
	}
	
	void GameLoopInput(){
		if(Input.GetKeyDown(KeyCode.G))
		{
			birdFactory.CreateBird(BirdType.ga);
		}
		else if(Input.GetKeyDown(KeyCode.N))
		{
			birdFactory.CreateBird(BirdType.ngan);
		}
		else if(Input.GetKeyDown(KeyCode.V))
		{
			birdFactory.CreateBird(BirdType.vit);
		}
		else if(Input.GetKeyDown(KeyCode.Escape)){
			pause();
		}
		else if(Input.GetKeyDown(KeyCode.F1)){
			showHelp();
		}
	}
	
	void showHelp(){
		_currentState = GameState.HELP;
		if(isPaused){
			UpdatePanels();
		}
		else{
			Time.timeScale = 0;
			UpdatePanels();
		}
	}
	
	void pause(){
		if(Time.timeScale>0){
				Time.timeScale = 0;
				pauseGame.SetActive(true);
				isPaused = true;
			}
			else{
				Time.timeScale = 1.0f;
				pauseGame.SetActive(false);
				isPaused = false;
			}
	}
	
	void waitToStart(){
		if(Input.anyKeyDown){
			_currentState = GameState.Playing;
			birdFactory.CreateBird(BirdType.ga);
			UpdatePanels();
			_score = 0;
			_penalty = 0;
		}
	}
	
	void waitToReset(){
		if(Input.anyKeyDown){
			_currentState = GameState.None;
			UpdatePanels();
		}
	}
	
	void waitToContinue(){
		if(Input.anyKeyDown){
			_currentState = GameState.Playing;
			if(isPaused){
				UpdatePanels();
			}
			else{
				Time.timeScale = 1.0f;
				UpdatePanels();
			}
		}
	}
	
	void UpdatePanels(){
		foreach(KeyValuePair<GameState,GameObject> it in _Panels){
			if(it.Key ==_currentState){
				it.Value.SetActive(true);
			}
			else
			{
				it.Value.SetActive(false);
			}
		}
	}
	
	public void Score(int a){
		_score+=a;
		if(_score>=120){
			Physics.gravity = new Vector3(0f, -5f, 0f);
		}
		else if(_score>=100){
			Physics.gravity = new Vector3(0f,-1.8f, 0f);
		}
		else if(_score>=80){
			Physics.gravity = new Vector3(0f,-1.2f, 0f);
		}
		else if(_score>=60){
			Physics.gravity = new Vector3(0f,-0.9f, 0f);
		}
		else if(_score>=40){
			Physics.gravity = new Vector3(0f,-0.6f, 0f);
		}
		else if(_score>=20){
			Physics.gravity = new Vector3(0f,-0.3f, 0f);
		}
		else{
			Physics.gravity = new Vector3(0f,-0.1f, 0f);
		}
	}
	
	public int GetScore(){
		return _score;
	}
	
	public void Penalty(int a){
		_penalty+=a;
		if(_penalty>=LOSE){
			_currentState = GameState.Gameover;
			StartCoroutine("StartClearScene");
		}
	}
	
	public void EnqueueBird(GameObject bird){
		if(_birdsInScene.Count >= MAX_QUEUE){
			GameObject go = _birdsInScene.Dequeue();
			GameObject.Destroy(go);
		}
		_birdsInScene.Enqueue(bird);
	}
	
	#endregion
	
	void Start(){
#if UNITY_STANDALONE
			Screen.SetResolution(600,600,false);
#endif
		
#if UNITY_WEBPLAYER
    		Screen.SetResolution(600,600,false);
#endif
		
#if UNITY_IPHONE 	
#endif
		
#if UNITY_ANDROID
#endif
		_Panels.Add(new KeyValuePair<GameState,GameObject>(GameState.None, Panel_NoneState));
		_Panels.Add(new KeyValuePair<GameState,GameObject>(GameState.Playing, Panel_PlayingState));
		_Panels.Add(new KeyValuePair<GameState,GameObject>(GameState.Gameover, Panel_GameoverState));
		_Panels.Add(new KeyValuePair<GameState,GameObject>(GameState.HELP, Panel_HelpState));
		_currentState = GameState.None;
		StartCoroutine("UpdatePanels");
		Instance = this;
	}
	
	void Update () {
		switch(_currentState){
		case GameState.Playing:
			GameLoopInput();
			break;
		case GameState.None:
			waitToStart();
			break;
		case GameState.Gameover:
			waitToReset();
			break;
		case GameState.HELP:
			waitToContinue();
			break;
		}
	}
	
	void FixedUpdate(){
		lblScore.text = _score.ToString();
	}
}

public enum GameState{
	None,
	Playing,
	Gameover,
	HELP
}
